#pragma once
#include <condition_variable>
#include <string>
#include <queue>
#include <memory>
#include <mutex>

#include <jdbc/mysql_driver.h>
#include <jdbc/mysql_connection.h>
#include <jdbc/cppconn/prepared_statement.h>


#include "Singleton.h"
using namespace std;

class MySQLPool {
public:
    MySQLPool(const std::string& url, const std::string& user, const std::string& password,
              const std::string& schema, int pool_size);
    ~MySQLPool();

    std::unique_ptr<sql::Connection> GetConnection();

    void ReturnConnection(std::unique_ptr<sql::Connection> con);

    void Close();

private:
    std::string _url;
    std::string _user;
    std::string _password;
    std::string _schema;
    int _pool_size;
    std::queue<std::unique_ptr<sql::Connection>> _pool;
    std::mutex _mutex;
    std::condition_variable _cond;
    std::atomic<bool> _b_stop;
};


class MySQLDao : public Singleton<MySQLDao> {
    friend class Singleton<MySQLDao>;

private:
    MySQLDao();

public:
    ~MySQLDao();

    bool UserLogin(const std::string& user, const std::string& password) const;

    void SelectSql(const std::string& sql) const;

    int RegUser(const std::string& name, const std::string& email, const std::string& pwd) const;

private:
    std::unique_ptr<MySQLPool> _pool;
};
